package com.eastmoney.emis.edda.domain.service.edda.impl;

import com.eastmoney.emis.edda.application.vo.EddaBindVo;
import com.eastmoney.emis.edda.application.vo.EddaOtpRegenerationVo;
import com.eastmoney.emis.edda.config.HsbcEddaConfig;
import com.eastmoney.emis.edda.domain.entity.EddaBind;
import com.eastmoney.emis.edda.domain.repository.EddaApplyTimesLimitRepository;
import com.eastmoney.emis.edda.domain.repository.HsbcEddaRepository;
import com.eastmoney.emis.edda.domain.service.EddaServeTimeService;
import com.eastmoney.emis.edda.domain.service.edda.*;
import com.eastmoney.emis.edda.domain.valueobject.ServiceType;
import com.eastmoney.emis.edda.infrastructure.exception.EddaException;
import com.eastmoney.emis.edda.infrastructure.exception.EddaExceptionStatus;
import com.eastmoney.emis.logger.LoggerFactory;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

/**
 * @description: Description
 * @projectName: EDDA-HSBC
 * @package: com.eastmoney.emis.edda.domain.service.impl
 * @author: 汪程程
 * @date: 2022/9/30 1:36 PM
 * @version: 1.0
 */
@Service
public class EddaServiceImpl implements EddaService {

    private static final Logger log = LoggerFactory.getLogger(EddaServiceImpl.class);

    @Autowired
    private EddaServeTimeService eddaServeTimeService;
    @Autowired
    private EddaAuthService eddaAuthService;
    @Autowired
    private HsbcEddaRepository hsbcEddaRepository;
    @Autowired
    private EddaApplyTimesLimitRepository timesLimitRepository;
    @Autowired
    private HsbcEddaConfig config;

    @Autowired
    private BindCheckDailyCache bindCheckDailyCache;

    @Override
    public boolean bindCheck(EddaBindCommand command) {

        LocalDateTime dateTime = bindCheckDailyCache.getObject(command.getClientId());
        if(dateTime == null) {
            dateTime = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);
        }
        int limitTimesDaily = timesLimitRepository.getMaxApplyTimesDaily();
        int applyTimesDaily = hsbcEddaRepository.getEddaApplyTimesDailyByClientIdAndStartTime(command.getClientId(), dateTime);
        return applyTimesDaily < limitTimesDaily;
    }

    @Override
    public EddaBindVo bind(EddaBindCommand command) {
        if (!bindCheck(command)) {
            throw new EddaException(EddaExceptionStatus.APPLY_OVER_LIMIT_DAILY);
        }

        EddaBind eddaBind = hsbcEddaRepository.findEddaBindByClientIdAndBankAccount(
                command.getClientId(), command.getBankCode(), command.getBankAccount());
        if (eddaBind != null && eddaBind.finished()) {
            throw new EddaException(EddaExceptionStatus.DUPLICATE_BIND);
        }
        if (eddaBind == null) {
            eddaBind = new EddaBind(command);
        } else {
            eddaBind.rebind(command.isHsbc());
            eddaBind.merge(command);
        }
        hsbcEddaRepository.save(eddaBind);
        if (eddaServeTimeService.serving(ServiceType.EDDA)) {
            return eddaAuthService.auth(command);
        }
        return eddaAuthService.authOffline(command);
    }

    @Override
    public EddaBind findEddaBind(EddaBindQuery query) {
        return hsbcEddaRepository.findEddaBindByClientIdAndBankAccount(
                query.getClientId(), query.getBankCode(), query.getBankCode());
    }

    @Override
    public void otpConfirm(EddaOtpConfirmCommand confirmCommand) {
        // 仅汇丰银行需要
        checkBankCode(confirmCommand.getBankCode());
        eddaAuthService.otpConfirm(confirmCommand);
    }

    @Override
    public EddaOtpRegenerationVo otpRegeneration(EddaOtpRegenerationCommand regenerationCommand) {
        checkBankCode(regenerationCommand.getBankCode());
        return eddaAuthService.otpRegeneration(regenerationCommand);
    }

    private void checkBankCode(String bankCode) {
        if (!config.getHsbcBankCode().equals(bankCode)) {
            throw new EddaException(EddaExceptionStatus.ERROR, "银行代码不匹配", true);
        }
    }
}
